package matse11.lspiel;

public class Operator {
	static short [][] dreheRechts(short feld [][]){
		short nummer= (short) (Spiel.getZug()%2);
		if(nummer==0) nummer=2;
		
		//prueft ob Stein an der Wand liegt
		boolean anderWand[]=new boolean [4];

		for(int i=0;i<feld.length;i++){
			anderWand[i]=true;
		}
		if(feld[0][0]==0&&feld[0][2]==0){
			anderWand[0]=false;
		}
		if(feld[0][0]==0&&feld[2][0]==0){
			anderWand[1]=false;
		}
		if(feld[3][0]==0&&feld[3][2]==0){
			anderWand[2]=false;
		}
		if(feld[0][3]==0&&feld[2][3]==0){
			anderWand[3]=false;
		}
			
		//bewegt Stein wenn dieser an der Wand liegt
		for(int i=0;i<feld.length;i++){
			if(anderWand[i]=true){
				int x=0;
				int y=0;
				if(i==0) x=1;
				if(i==1) y=-1;
				if(i==2) x=-1;
				if(i==3) y=1;
				bewege(feld, x, y);
				break;
			}
		}
		
		//setzt den Stein auf Spielernummer 1
		for(int i=0;i<feld.length;i++){
			for (int j=0;j<feld.length;j++){
				if (feld[i][j]==2){
					feld[i][j]=1;
				}
			}
		}
		
		//prueft ob der Stein links gekippt ist und wo der Eckstein liegt
		
		boolean linksgekippt=false;
		int positionecksteinx=0;
		int positionecksteiny=0;
		int positionmittesteinx=0;
		int positionmittesteiny=0;
			for(int i=0;i<feld.length;i++){
				for(int j=0;j<feld.length;j++){	
					if((i!=0&&j!=0)&&(i!=0&&j!=3)&&(i!=3&&j!=0)&&(i!=3&&j!=3)){
							if ((feld[i][j]==1)&&(feld[i-1][j]+feld[i+1][j]+feld[i][j-1]+feld[i][j+1])==2){
									if ((feld[i][j+1]==1)&&(feld[i][j+2]==1)){
										positionecksteinx=j;
										positionecksteiny=i;
										if(feld[i+1][j]==1){
											linksgekippt=true;
										}
									}
									if ((feld[i][j-1]==1)&&(feld[i][j-2]==1)){
										positionecksteinx=j;
										positionecksteiny=i;
										if(feld[i-1][j]==1){
											linksgekippt=true;
										}
									}
									if ((feld[i+1][j]==1)&&(feld[i+2][j]==1)){
										positionecksteinx=j;
										positionecksteiny=i;
										if(feld[i][j+1]==1){
											linksgekippt=true;
										}
									}
									if ((feld[i-1][j]==1)&&(feld[i-2][j]==1)){
										positionecksteinx=j;
										positionecksteiny=i;
										if(feld[i][j-1]==1){
											linksgekippt=true;
										}
									}
										
							}
					}
				}
			}
			
		//eigentliche Drehmethode
		
		if(feld[positionmittesteiny+1][positionmittesteinx]==1){				
			feld[positionmittesteiny+1][positionmittesteinx]=0;
		}
		if(feld[positionmittesteiny+1][positionmittesteinx+1]==1){
			feld[positionmittesteiny+1][positionmittesteinx+1]=0;
		}
		if(feld[positionmittesteiny][positionmittesteinx+1]==1){
			feld[positionmittesteiny][positionmittesteinx+1]=0;
		}
		if(feld[positionmittesteiny-1][positionmittesteinx+1]==1){
			feld[positionmittesteiny-1][positionmittesteinx+1]=0;
		}
		if(feld[positionmittesteiny-1][positionmittesteinx]==1){
			feld[positionmittesteiny-1][positionmittesteinx]=0;
		}
		if(feld[positionmittesteiny-1][positionmittesteinx-1]==1){
			feld[positionmittesteiny-1][positionmittesteinx-1]=0;
		}
		if(feld[positionmittesteiny][positionmittesteinx-1]==1){
			feld[positionmittesteiny][positionmittesteinx-1]=0;
		}
		if(feld[positionmittesteiny+1][positionmittesteinx-1]==1){
			feld[positionmittesteiny+1][positionmittesteinx-1]=0;
		}
	
		if(linksgekippt){
			int x=(positionmittesteinx-positionecksteinx)*2;
			int y=(positionmittesteiny-positionecksteiny)*2;
			feld[y][x+1]=0;
			feld[y][x-1]=0;
		}
		if(!linksgekippt){
			spiegleVe(feld);
			int x=(positionmittesteinx-positionecksteinx)*2;
			int y=(positionmittesteiny-positionecksteiny)*2;
			feld[y][x+1]=0;
			feld[y][x-1]=0;
			spiegleVe(feld);
		}
		
		for(int i=0;i<feld.length;i++){
			for (int j=0;j<feld.length;j++){
				if (feld[i][j]==1) feld[i][j]=nummer;
			}
		}
				
		return feld;
	}
	
	static short [][] dreheLinks(short feld [][]){
		return dreheRechts(dreheRechts(dreheRechts(feld)));
	}

	static short [][] spiegleHo(short[][] feld) {
		short [] tmpzeile = new short [4];
		int zeilenzahl = 0;
		for(int i=0; i<feld.length-1;i++){
			for(int j=0; j<feld.length;j++){
				if(feld[i][j]!=0){
					zeilenzahl=i;
				}
			}
		}
		for(int j=0; j<feld.length;j++){
			tmpzeile[j]=feld[zeilenzahl][j];
			feld[zeilenzahl][j]=feld[zeilenzahl+1][j];
			feld[zeilenzahl+1][j]=tmpzeile[j];
		}
		return feld;
		
	}
	
	static short [][] spiegleVe(short[][] feld) {
		return dreheRechts(dreheRechts(spiegleHo(feld)));
	}


	public static short [][] feldDrehen(short[][] feld) {
		short [][]tmp=new short[4][4];
//		erzeugen eines temporaeren feldes, damit ich das zurueckgeben kann
		for(int  l=0;l<tmp.length;l++){
			for(int k=0;k<tmp[0].length;k++){
				tmp[tmp.length-1-k][l]=feld[l][k];
			}
		}
		return tmp;
	}
	
	public static short [][] feldSpiegel(short[][]feld){
		short [][]tmp=new short[4][4];
		for(int i=0;i<feld.length;i++){
			for(int j=0;j<feld[0].length;j++){
				tmp[feld.length-1-i][j]=feld[i][j];
			}
		}
		return tmp;
	}
	

	private static void bewege(short[][] feld, int x, int y) {
		if(x<0){
			for(int i=0;i<feld.length;i++){
				for(int j=0;j<feld.length;j++){
					feld[i][j+x]=feld[i][j];
					feld[i][j]=0;
				}
			}
		}
		if(x>0){
			for(int i=feld.length-1;i>0;i--){
				for(int j=0;j<feld.length;j++){
					feld[i][j+x]=feld[i][j];
					feld[i][j]=0;
				}
			}
		}
		if(y<0){
			for(int i=0;i<feld.length;i++){
				for(int j=0;j<feld.length;j++){
					feld[i+y][j]=feld[i][j];
					feld[i][j]=0;
				}
			}
		}
		if(y>0){
			for(int i=0;i<feld.length;i++){
				for(int j=feld.length-1;j>0;j--){
					feld[i+y][j]=feld[i][j];
					feld[i][j]=0;
				}
			}
		}
		
	}
	public static boolean pruefe(short[][]ak,short[][][]positionen){
		short[][]feld;
		short[][]tmp=new short[4][4];
		boolean gleich=false;
		int zaehler=0;
		int internerZaehler=0;
//		ueberprueft ob spieler 1 oder 2 dran ist und invertiert das feld ggf.
		if(Spiel.getZug()%2==0){
			feld=invertiere(ak);
		}
		else{
			feld=ak;
		}
		
		while(zaehler<15){
//			geht hier alle moeglichen gewinnsituationen durch
			while(internerZaehler<=7){
				if(internerZaehler==0){
					tmp=Logik.getGewinnsituationen()[zaehler];
				}
				else if(internerZaehler==1){
					tmp=feldDrehen(tmp);
				}
				else if(internerZaehler==2){
					tmp=feldDrehen(tmp);
				}
				else if(internerZaehler==3){
					tmp=feldDrehen(tmp);
				}
				else if(internerZaehler==4){
					tmp=feldDrehen(tmp);
					tmp=feldSpiegel(tmp);
				}
				else if(internerZaehler==5){
					tmp=feldDrehen(tmp);
				}
				else if(internerZaehler==6){
					tmp=feldDrehen(tmp);
				}
				else if(internerZaehler==7){
					tmp=feldDrehen(tmp);
				}
	//			ueberprueft, ob das feld und tmp uebereinstimmen wenn ja wird true zurueckgegeben 
				for(int i=0;i<feld.length;i++){
					for(int j=0;j<feld[0].length;j++){
						if(feld[i][j]==tmp[i][j]){
							gleich=true;
						}
						else{
							gleich=false;
							break;
						}
					}
				}
				if(gleich){
					return true;
				}
				internerZaehler++;
			}
			zaehler++;
		}
		return false;
	}
	
	private static short[][] invertiere(short[][] feld){
		for(int i=0; i<feld.length;i++){
			for(int j=0; j<feld.length; j++){
				if(feld[i][j]==1){
					feld[i][j]=2;
				}
				else if(feld[i][j]==2){
					feld[i][j]=1;
				}
			}
		}
		return feld;
	}
}
